import _ from "lodash";
import { ElMessage } from "element-plus";
const inputElements = [];

function clickHandle(this: any) {
	if (!_.isFunction(this.input.click)) {
		throw new Error("input Element 创建失败");
	}

	// 可在 @before-click return false 来阻止文件选择器弹出
	if (_.isFunction(_.get(this.vnode, "props.onBeforeClick"))) {
		if (!this.vnode.props.onBeforeClick()) {
			return;
		}
	}

	this.input.click();
}

function stop(e: MouseEvent) {
	e.stopPropagation();
	e.preventDefault();
}

/**
 * @type {import('vue').Directive}
 */
export default {
	mounted(el: any, binding: any, vnode: any) {
		const id = _.uniqueId();

		const element = {
			id,
			vnode,
			input: document.createElement("input")
		};

		inputElements.push(element);

		const fileType = _.get(binding.value, "type", []);
		const fileTypeArray = _.isArray(fileType) ? _.map(fileType, type => `.${type}`) : [`.${fileType}`];

		const limit = _.get(binding.value, "limit", 1);

		const fileHandle = (file: File) => {
			// 没选择文件
			if ((_.isArray(file) && file.length === 0) || !(file instanceof File)) {
				return;
			}

			_.isFunction(vnode.props.onUpload) && vnode.props.onUpload(file);
		};

		element.input.type = "file";

		// 文件格式
		element.input.accept = _.join(fileTypeArray, ",");

		// 是否多选
		element.input.multiple = limit > 1;

		element.input.addEventListener("change", e => {
			let pass = true;
			_.forEach((e.target as any).files, file => {
				// 验证文件格式
				const currentFileType = file.name.slice(file.name.lastIndexOf("."));
				if (!_.includes(fileTypeArray, currentFileType)) {
					ElMessage.error("文件格式错误");
					pass = false;
					return false;
				}
			});

			if (!pass) {
				element.input.value = "";
				return;
			}

			fileHandle(limit > 1 ? (e.target as any).files : (e.target as any).files[0]);

			element.input.value = "";
		});

		el.dropHandle = (e: any) => {
			fileHandle(limit > 1 ? e.dataTransfer.files : e.dataTransfer.files[0]);
			stop(e);
		};

		el.addEventListener("click", clickHandle.bind(element));
		el.addEventListener("dragenter", stop, false);
		el.addEventListener("dragover", stop, false);
		el.addEventListener("drop", el.dropHandle, false);
	},
	beforeUnmount(el: any) {
		el.removeEventListener("click", clickHandle);
		el.removeEventListener("dragenter", stop);
		el.removeEventListener("dragover", stop);
		el.removeEventListener("drop", el.dropHandle);
	}
};
